home *** CD-ROM | disk | FTP | other *** search
- head 1.5;
- branch ;
- access ;
- symbols srv030:1.5 srv027:1.5 srv026:1.5 srv024:1.5 srv021:1.5 srv018:1.5 srv014:1.5 srv010:1.5 srv008:1.5 srv007:1.5 srv006:1.5 srv004:1.5;
- locks ; strict;
- comment @ * @;
-
-
- 1.5
- date 92.04.29.22.32.45; author kupfer; state Exp;
- branches ;
- next 1.4;
-
- 1.4
- date 91.11.14.20.28.57; author kupfer; state Exp;
- branches ;
- next 1.3;
-
- 1.3
- date 91.10.18.18.49.36; author kupfer; state Exp;
- branches ;
- next 1.2;
-
- 1.2
- date 91.10.04.14.17.12; author kupfer; state Exp;
- branches ;
- next 1.1;
-
- 1.1
- date 91.10.02.18.25.41; author kupfer; state Exp;
- branches ;
- next ;
-
-
- desc
- @Test program to create a tree of processes to test process creation
- and termination.
- @
-
-
- 1.5
- log
- @Add USE_STDIO ifdef.
- @
- text
- @/*
- * processTree.c --
- *
- * Test program to do lots of forks and execs. Basically the program
- * spawns a small tree of processes, in which a process forks off some
- * children, waits a random interval, then exits.
- *
- * Usage: processTree [ numSecs ]
- *
- * where "numSecs" is the minimum number of seconds to run. (The
- * default is to run forever.) After numSecs seconds the top-level
- * process stops creating new processes, and eventually the program
- * exits.
- *
- * Copyright 1991 Regents of the University of California
- * Permission to use, copy, modify, and distribute this
- * software and its documentation for any purpose and without
- * fee is hereby granted, provided that this copyright
- * notice appears in all copies. The University of California
- * makes no representations about the suitability of this
- * software for any purpose. It is provided "as is" without
- * express or implied warranty.
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: /user5/kupfer/spriteserver/tests/processTree/RCS/processTree.c,v 1.4 91/11/14 20:28:57 kupfer Exp Locker: kupfer $ SPRITE (Berkeley)";
- #endif /* not lint */
-
- #include <errno.h>
- #include <sprite.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/wait.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/resource.h>
- #include <test.h>
- #include <unistd.h>
-
- #define USE_STDIO /* use printf instead of Test_PutTime */
-
- #define NUM_CHILDREN_1ST 2 /* number of immediate children to keep
- * running */
- #define MAX_CHILDREN_2ND 10 /* maximum number of children to be
- * created by a first-generation child */
- #define MAX_PRINTFS 5 /* maximum number of printfs for a
- * process to do before exiting */
- #define MAX_SLEEP_TIME 20 /* maximum number of seconds to sleep
- * between printf's */
-
- extern int FromInterval();
-
- /* Forward references: */
-
- static void BeAChild();
- static int Lookup();
- static pid_t MakeChild();
- static void PrintfLoop();
- static void PrintTime();
- static void ReapChildren();
- static void SleepSome();
-
-
- /*
- *----------------------------------------------------------------------
- *
- * main --
- *
- * Run forever; start a new top-level child when one exits.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- void
- main(argc, argv)
- int argc;
- char **argv;
- {
- int child;
- pid_t children[NUM_CHILDREN_1ST];
- pid_t deadDescendant;
- time_t stopTime = 0; /* if non-zero, don't create new processes
- * after this time */
-
- /*
- * Initialization.
- */
- for (child = 0; child < NUM_CHILDREN_1ST; ++child) {
- children[child] = MakeChild(TRUE);
- }
- if (argc > 1) {
- stopTime = time((time_t *)0) + atoi(argv[1]);
- }
-
- /*
- * When a direct descendant dies, start a replacement, up until the
- * stopping time (if any). If we're running as the initial process, we
- * inherit 2nd generation processes as well. When those die, take no
- * additional action.
- */
-
- for (;;) {
- deadDescendant = wait((union wait *)0);
- if (deadDescendant < 0) {
- if (stopTime == 0 || time((time_t *)0) < stopTime) {
- perror("Wait at top level failed");
- exit(1);
- }
- exit(0);
- }
- child = Lookup(deadDescendant, children);
- if (child != -1) {
- if (stopTime == 0 || time((time_t *)0) < stopTime) {
- children[child] = MakeChild(TRUE);
- }
- }
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * MakeChild --
- *
- * Make a child process.
- *
- * Results:
- * In the parent, returns the pid of the child. In the child, never
- * returns.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static pid_t
- MakeChild(moreChildren)
- Boolean moreChildren; /* should the child make addition children? */
- {
- pid_t childPid;
-
- childPid = fork();
- switch (childPid) {
- case -1:
- perror("Can't create child");
- exit(1);
- break;
- case 0:
- BeAChild(moreChildren);
- exit(0);
- break;
- }
-
- return childPid;
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * BeAChild --
- *
- * Create some number of child processes if asked to do so. Then do a
- * random number of printfs, sleeping a random time between printfs
- * and checking for dead children. Then return.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- BeAChild(makeChildren)
- Boolean makeChildren;
- {
- int numChildren;
- int child;
-
- /*
- * Reinitialize the random number generator, using our pid. Otherwise,
- * all the processes run in lock step.
- */
- srandom(getpid());
-
- /*
- * Even though we're supposed to make children, we don't want any
- * grandchildren.
- */
- if (makeChildren) {
- numChildren = FromInterval(1, MAX_CHILDREN_2ND);
- for (child = 0; child < numChildren; ++child) {
- (void)MakeChild(FALSE);
- }
- }
-
- PrintfLoop(makeChildren);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * PrintfLoop --
- *
- * Do a random number of printfs over a random time interval. Each
- * time through the loop, reap any children that have died.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- PrintfLoop(expectChildren)
- Boolean expectChildren; /* should there be children to reap? */
- {
- int numMessages = FromInterval(1, MAX_PRINTFS);
- int msg; /* message (printf) number */
-
- for (msg = 0; msg < numMessages; ++msg) {
- PrintTime();
- SleepSome();
- if (expectChildren) {
- ReapChildren();
- }
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * PrintTime --
- *
- * Backspace over the previous time message and write the current
- * time.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- PrintTime()
- {
- time_t now;
- #ifdef USE_STDIO
- char buf[26];
- #endif
-
- now = time((time_t *)0);
- #ifdef USE_STDIO
- strcpy(buf, ctime(&now));
- buf[24] = '\0';
- printf("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b%s",
- buf);
- fflush(stdout);
- #else
- Test_PutTime(now, TRUE);
- #endif
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * SleepSome --
- *
- * Pick a random number of seconds and sleep for that long.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- SleepSome()
- {
- int numSecs;
-
- numSecs = FromInterval(1, MAX_SLEEP_TIME);
- sleep(numSecs);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * ReapChildren --
- *
- * Reap any dead children. If there aren't any currently, return.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- ReapChildren()
- {
- pid_t childPid;
-
- for (;;) {
- childPid = wait3((union wait *)0, WNOHANG, (struct rusage *)0);
- /* no children died */
- if (childPid == 0) {
- break;
- }
- /* all our children died before we did */
- if (childPid < 0 && errno == ECHILD) {
- break;
- }
- if (childPid < 0) {
- perror("Wait for child failed");
- exit(1);
- }
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Lookup --
- *
- * Find the given child in the table of children.
- *
- * Results:
- * Returns the table index for the child, or -1 if the child isn't in
- * the table.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static int
- Lookup(child, childTable)
- pid_t child;
- pid_t *childTable; /* table with NUM_CHILDREN_1ST entries */
- {
- int index;
-
- for (index = 0; index < NUM_CHILDREN_1ST; ++index) {
- if (childTable[index] == child) {
- return index;
- }
- }
-
- return -1;
- }
-
- @
-
-
- 1.4
- log
- @Fix some comments.
- @
- text
- @d26 1
- a26 1
- static char rcsid[] = "$Header: /r3/kupfer/spriteserver/tests/processTree/RCS/processTree.c,v 1.3 91/10/18 18:49:36 kupfer Exp Locker: kupfer $ SPRITE (Berkeley)";
- d41 2
- d268 3
- d273 7
- d281 1
- @
-
-
- 1.3
- log
- @Lint. Take an argument specifying how long to run.
- @
- text
- @d2 1
- a2 1
- * forkExec.c --
- d7 7
- d26 1
- a26 1
- static char rcsid[] = "$Header: /r3/kupfer/spriteserver/tests/processTree/RCS/processTree.c,v 1.2 91/10/04 14:17:12 kupfer Exp Locker: kupfer $ SPRITE (Berkeley)";
- @
-
-
- 1.2
- log
- @Changes to run under early version of Sprite server. Lint.
- @
- text
- @d19 1
- a19 1
- static char rcsid[] = "$Header: /r3/kupfer/spriteserver/tests/processTree/RCS/processTree.c,v 1.1 91/10/02 18:25:41 kupfer Exp Locker: kupfer $ SPRITE (Berkeley)";
- d73 3
- a75 1
- main()
- d80 2
- d89 3
- d94 4
- a97 3
- * When a direct descendant dies, start a replacement. If we're
- * running as the initial process, we inherit 2nd generation processes
- * as well. When those die, take no additional action.
- d99 1
- a99 1
-
- d103 5
- a107 2
- perror("Wait at top level failed");
- exit(1);
- d111 3
- a113 1
- children[child] = MakeChild(TRUE);
- d260 1
- a260 1
- now = time(0);
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d19 1
- a19 1
- static char rcsid[] = "$Header: /sprite/lib/forms/RCS/proto.c,v 1.5 91/02/09 13:24:44 ouster Exp $ SPRITE (Berkeley)";
- d25 1
- a26 1
- #include <sys/file.h>
- d31 2
- a33 2
- typedef int pid_t; /* should be in <sys/types.h> */
-
- d43 1
- a43 1
- int lockFile; /* file descriptor for shared lock file */
- a47 1
- static void ClearLock();
- a52 1
- static void SetLock();
- a81 6
- lockFile = open("/users/kupfer/tmp/LockFile", O_RDWR|O_CREAT, 0644);
- if (lockFile < 0) {
- perror("Can't open lock file");
- exit(1);
- }
-
- d93 1
- a93 1
- deadDescendant = wait(0);
- d237 1
- a237 1
- * Uses a lock file to ensure that the printf is atomic.
- a244 1
- char buffer[1024]; /* what we actually print */
- a245 1
- int i;
- a246 1
- SetLock();
- d248 1
- a248 12
- for (i = 0; i < 25; ++i) {
- buffer[i] = '\b';
- }
- buffer[i] = '\0';
- strcat(buffer, ctime(&now));
- /*
- * Null out the final newline.
- */
- buffer[strlen(buffer)-1] = '\0';
- printf(buffer);
- fflush(stdout);
- ClearLock();
- d300 1
- a300 1
- childPid = wait3(0, WNOHANG, 0);
- a304 4
- /* no children died (Sprite returns this, when it should return 0) */
- if (childPid < 0 && errno == EWOULDBLOCK) {
- break;
- }
- a349 51
-
- /*
- *----------------------------------------------------------------------
- *
- * SetLock --
- *
- * Lock the lock file.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- SetLock()
- {
- if (flock(lockFile, LOCK_EX) < 0) {
- perror("flock failed");
- exit(1);
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * ClearLock --
- *
- * Release the lock file
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- ClearLock()
- {
- if (flock(lockFile, LOCK_UN|LOCK_EX) < 0) {
- perror("Couldn't release lock file");
- exit(1);
- }
- }
- @
-